package com.ygqh.baby.controller.admin;

import com.alibaba.fastjson.JSON;
import com.ygqh.baby.ao.CodeType;
import com.ygqh.baby.ao.Message;
import com.ygqh.baby.ao.QueryInfo;
import com.ygqh.baby.ao.ResultSet;
import com.ygqh.baby.controller.utils.DocumentHandler;
import com.ygqh.baby.po.YgSupplier;
import com.ygqh.baby.po.YgSupplierSchedule;
import com.ygqh.baby.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;

@Controller
@RequestMapping("/admin/supplierschedule")
public class SupplierScheduleController extends BaseController<Object, java.lang.Long> {

    @Autowired
    private YgSupplierScheduleService ygSupplierScheduleService;
    @Autowired
    private YgReturnOrderService YgReturnOrderService;
    @Autowired
    private FileService fileService;

    @Autowired
    private YgFrameCodeService ygFrameCodeService;
    @Autowired
    private YgSupplierService ygSupplierService;
    @Autowired
    private YgSupplierReconciliationService ygSupplierReconciliationService;

    @RequestMapping("searchSchedule")
    @ResponseBody
    public Map<String, Object> searchSchedule(Long supplierId, QueryInfo queryInfo) {

        ResultSet<YgSupplierSchedule> resultSet = ygSupplierScheduleService.search(queryInfo, supplierId);

        return resultSet.toDatatables(null);
    }

    @RequestMapping("saveSchedule")
    @ResponseBody
    public Message saveSchedule(String s) {
        YgSupplierSchedule schedule = JSON.parseObject(s, YgSupplierSchedule.class);
        if (schedule.getId() == null) {
            schedule.setCreateBy(getSession().getTrueName());
            schedule.setCreateTime(new Date());
            String scheduleCode = ygFrameCodeService.getFrameCode(CodeType.Schedule, new Date(), 4);
            schedule.setScheduleCode(scheduleCode);
            //判断当前商家是否存在相同的区间
            if (checkExistSupplierSchedule(schedule.getSupplierId(), schedule.getStartDate())) {
                return ERROR_MESSAGE;
            }
        } else {
            schedule.setUpdateBy(getSession().getTrueName());
            schedule.setUpdateTime(new Date());
        }

        ygSupplierScheduleService.saveOrUpdate(schedule);
        return SUCCESS_MESSAGE;
    }

    private boolean checkExistSupplierSchedule(Long supplierId, Date startDate) {
        QueryInfo queryInfo = new QueryInfo();
        queryInfo.setEnd(100);
        List<YgSupplierSchedule> list = ygSupplierScheduleService.selectSupplierSchedule(queryInfo, supplierId);
        if (list != null) {
            //是否存在多个endDate 为空的
            if (list.stream().filter(p -> p.getEndDate() == null).count() > 0) {
                return true;
            }
            if (list.stream().filter(p -> p.getEndDate().after(startDate)).count() > 0) {
                return true;
            }
        }
        return false;
    }

    @RequestMapping("exportData")
    public void exportData(Long supplierId, Date startDate, Date endDate, HttpServletRequest request, HttpServletResponse response) throws IOException {
        /*List<Map<String, Object>> order = YgReturnOrderService.selectSendOrderBySupplier(supplierId, startDate, endDate);
        List<Map<String, Object>> returnData = YgReturnOrderService.selectReturnBySupplier(supplierId, startDate, endDate);*/
        Map<String, Object> dataMap = ygSupplierReconciliationService.findExportDataDetail(startDate, endDate, supplierId);
        byte[] bytes = fileService.downloadFromOss("template/yiigoo_supplier_order.xlsx");
        DocumentHandler.DownloadExcel(bytes, "对账数据.xlsx", dataMap, request, response);
    }

    @RequestMapping("export")
    public void export(Date startDate, Date endDate, HttpServletRequest request, HttpServletResponse response) {

        List<Map<String, Object>> dataMaps = new ArrayList<>();
        List<YgSupplier> ygSuppliers = ygSupplierService.find();
        List<Long> supplierIdListWithTrade = ygSupplierService.findSupplierIdListWithTrade(startDate, endDate);
        List<Map<String, Object>> returnedBySupplier = YgReturnOrderService.findReturnedInfoBySupplier(startDate, endDate, null, true);
        Map<Long, List<Map<String, Object>>> supplierMap = returnedBySupplier.stream().collect(Collectors.groupingBy(m -> (Long) m.get("supplierId")));

        // 创建一个线程池
        ExecutorService executorService = Executors.newFixedThreadPool(5);
        // 创建多个有返回值的任务
        List<Future> list = new ArrayList<>();
        ygSuppliers.forEach(ygSupplier -> {
            if (!supplierIdListWithTrade.contains(ygSupplier.getId())) {
                return;
            }
            Callable<Map<String, Object>> callable = () -> getThirdSupplierOrder(ygSupplier, startDate, endDate);
            Future<Map<String, Object>> future = executorService.submit(callable);
            list.add(future);
        });
        list.forEach(item -> {
            try {
                Map<String, Object> thirdSupplierOrder = (Map<String, Object>) item.get();
                Long supplierId = (Long) thirdSupplierOrder.get("supplierId");
                String paymentMode = (String) thirdSupplierOrder.get("paymentMode");
                if (supplierMap.containsKey(supplierId)) {
                    List<Map<String, Object>> returnList = supplierMap.get(supplierId);
                    Object refundPrice = returnList.get(0).get("refundPrice");
                    Object refundAmount = returnList.get(0).get("refundAmount");
                    Object refundCostPrice = returnList.get(0).get("refundCostPrice");
                    Object refundAccountPrice = returnList.get(0).get("refundAccountPrice");
                    thirdSupplierOrder.put("refundPrice", refundPrice);
                    thirdSupplierOrder.put("refundAmount", refundAmount);
                    thirdSupplierOrder.put("refundCostPrice", refundCostPrice);
                    thirdSupplierOrder.put("refundAccountPrice", refundAccountPrice);
                } else {
                    thirdSupplierOrder.put("refundPrice", BigDecimal.ZERO);
                    thirdSupplierOrder.put("refundAmount", BigDecimal.ZERO);
                    thirdSupplierOrder.put("refundCostPrice", BigDecimal.ZERO);
                    thirdSupplierOrder.put("refundAccountPrice", BigDecimal.ZERO);
                }
                thirdSupplierOrder.put("paymentMode", paymentMode);

                dataMaps.add(thirdSupplierOrder);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }

        });

        byte[] bytes = fileService.downloadFromOss("template/supplier_month_report.xlsx");
        Map<String, Object> dataMap = new HashMap<String, Object>();

        dataMap.put("data", dataMaps);

        System.out.println(JSON.toJSONString(dataMaps));
        DocumentHandler.DownloadExcel(bytes, "商家月账单.xlsx", dataMap, request, response);
    }

    private Map<String, Object> getThirdSupplierOrder(YgSupplier ygSupplier, Date startDate, Date endDate) {
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("supplierId", ygSupplier.getId());
        resultMap.put("paymentMode", ygSupplier.getPaymentMode().getTitle());
        // 已发货订单
        List<Map<String, Object>> orderList = YgReturnOrderService.selectSendOrderBySupplier(ygSupplier.getId(), startDate, endDate);

        orderList = orderList.stream().filter(o -> ((Long) o.get("userId")).compareTo(40L) != 0).collect(Collectors.toList());
        BigDecimal totalOrderPrice = BigDecimal.ZERO;
        BigDecimal totalAccountPrice = BigDecimal.ZERO;
        BigDecimal totalCostPrice = BigDecimal.ZERO;
        Long totalQuantity = 0L;

        Map<Object, List<Map<String, Object>>> orderMap = orderList.stream().collect(Collectors.groupingBy(o -> o.get("orderId")));
        for (Map.Entry<Object, List<Map<String, Object>>> entry : orderMap.entrySet()) {
            List<Map<String, Object>> detailList = entry.getValue();

            BigDecimal accountPrice = (BigDecimal) detailList.get(0).get("accountPrice");
            BigDecimal subProductPrice = detailList.stream().map(od -> ((BigDecimal) od.get("salePrice"))
                    .multiply(new BigDecimal((Long) od.get("quantity")))).reduce(BigDecimal.ZERO, BigDecimal::add);
            BigDecimal subCostPrice = detailList.stream().map(od -> ((BigDecimal) od.get("costPrice"))
                    .multiply(new BigDecimal((Long) od.get("quantity")))).reduce(BigDecimal.ZERO, BigDecimal::add);
            Long subQuantity = detailList.stream().map(od -> (Long) od.get("quantity")).reduce(0L, (a, b) -> (a + b));
            totalQuantity = totalQuantity + subQuantity;
            totalCostPrice = totalCostPrice.add(subCostPrice);
            totalOrderPrice = totalOrderPrice.add(subProductPrice);
            totalAccountPrice = totalAccountPrice.add(accountPrice);
        }
        resultMap.put("totalOrderPrice", totalOrderPrice);
        resultMap.put("totalAccountPrice", totalAccountPrice);
        resultMap.put("totalCostPrice", totalCostPrice);
        resultMap.put("totalQuantity", totalQuantity);
        resultMap.put("supplierName", ygSupplier.getSupplierName());

        return resultMap;
    }
}
